package cn.buk.qms.captcha;

import cn.buk.jedis.RedisDao;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import javax.imageio.ImageIO;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * Date: 2014-7-7
 * @author yfdai
 */
@Component
public class CaptchaServiceImpl implements CaptchaService,InitializingBean {

    private DefaultKaptcha producer;

    private List<String> preDefinedTexts;

    private int textCount = 0;

    @Autowired
    private RedisDao redisDao;

    @Override
    public void afterPropertiesSet() {
        producer = new DefaultKaptcha();

        producer.setConfig( new Config( new Properties() ) );
    }

    @Override
    public String generateCaptchaKey(final String key)
    {
        // 生成captcha的内容
        String value = getCaptchaText();

        // 保存到redis中，有效期5分钟
        redisDao.setAndExpire(key, value.getBytes(UTF_8), 300);

        return value;
    }

    @Override
    public List<String> getPreDefinedTexts()
    {
        return preDefinedTexts;
    }

    @Override
    public void setPreDefinedTexts( List<String> preDefinedTexts )
    {
        this.preDefinedTexts = preDefinedTexts;
    }

    private String getCaptchaText()
    {
        if ( preDefinedTexts != null && !preDefinedTexts.isEmpty() )
        {
            String text = preDefinedTexts.get( textCount );

            textCount = ( textCount + 1 ) % preDefinedTexts.size();

            return text;
        }
        else
        {
            return producer.createText();
        }
    }

    @Override
    public byte[] generateCaptchaImage( String captchaText )
            throws CaptchaException
    {
        BufferedImage image = producer.createImage( captchaText );

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try
        {
            ImageIO.write(image, "jpg", out);
        }
        catch ( IOException e )
        {
            throw new CaptchaException( "Failed to write captcha stream!", e );
        }

        return out.toByteArray();
    }

    /**
     * 验证录入的校验码是否正确
     * @param captchaKey
     * @param captchaValue
     * @return
     */
    @Override
    public boolean validateCaptcha( final String captchaKey, final String captchaValue ) {

        String text = redisDao.getStr(captchaKey);

        return text != null && text.equals(captchaValue);
    }
}
